package gigapaint;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

@SuppressWarnings("serial")
public class MyPolygon extends Polygon implements Paintable
{
	private Color color;
	private List<Point> pointList;
	int size = 1;

	public MyPolygon(ArrayList<Point> pointList, Color color)
	{
		super();
		this.pointList = new ArrayList<Point>();

		this.color = color;
		for (Point point : pointList)
		{
			this.addPoint(point.x, point.y);
		}
	}

	@Override
	public void addPoint(int x, int y)
	{
		pointList.add(new Point(x, y));
		super.addPoint(x, y);
	}

	public void addPoint(Point p)
	{
		super.addPoint(p.x, p.y);
		pointList.add(p);
	}

	@Override
	public void painting(Graphics2D g2d, boolean isDotted)
	{
		BasicStroke b;
		g2d.setPaint(color);
		if (isDotted == true)
		{
			float[] dash = { 8.0f, 3.0f };
			b = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
					BasicStroke.JOIN_BEVEL, 10.0f, dash, 0.0f); // Zum
																// gestrichelt
																// zeichnen
		}
		else
		{
			b = new BasicStroke(1.0f);
		}
		g2d.setStroke(b);
		g2d.drawPolygon(this);

	}

	@Override
	public void setEnd(Point point)
	{
		this.addPoint(point);

	}

	public ArrayList<MyLine> fill(Color fillingColor)
	{
		ArrayList<MyLine> scanlines = new ArrayList<MyLine>();
		Rectangle bounds = this.getBounds();

		// Iteration über alle Punkte

		for (int aktY = (int) bounds.getMinY(); aktY <= (int) bounds.getMaxY(); aktY++)
		{
			ArrayList<Point> schnittpunkte = getSchnittpunkte(aktY);


			Iterator<Point> it = schnittpunkte.iterator();
			Point actPoint = null, previousPoint = null;
			boolean paint = false;	//Parität

			while (it.hasNext())
			{
				previousPoint = actPoint;
				actPoint = it.next();
				if (paint == true)
				{
					paint = false;
					scanlines.add(new MyLine(previousPoint, actPoint, fillingColor,
							size));
				}
				else
				{
					paint = true;
				}
			}

		}

		return scanlines;
	}

	/**
	 * Liefert die Schnittpunkte der aktuellen Scanline aufsteigend sortiert
	 * zurück
	 * 
	 * @param actY
	 *            Y-Position der aktuellen Scanline
	 * @return
	 */
	private ArrayList<Point> getSchnittpunkte(int actY)
	{
		ArrayList<Point> schnittpunkte = new ArrayList<Point>();
		Iterator<Point> it = pointList.iterator();
		Point actPoint, previousPoint;
		if (it.hasNext())
		{
			actPoint = pointList.get(pointList.size()-1);

			while (it.hasNext())
			{
				previousPoint = actPoint;
				actPoint = it.next();
				if (((previousPoint.getY() <= actY) && (actPoint.getY() > actY))
						|| ((actPoint.getY() <= actY) && (previousPoint.getY() > actY)))
				{
					schnittpunkte.add(new Point(
							(int) (previousPoint.x + (((double)actPoint.x - (double)previousPoint.x)
									/ ((double)actPoint.y - (double)previousPoint.y)) * ((double)actY - (double)previousPoint.y)),
							actY));
				}
			}
		}
		Collections.sort(schnittpunkte, new PointCompare());
		return schnittpunkte;
	}

}
